﻿/*========================== 
 * @author 郑金泉
 * @desc 实体实用工具
 * ========================= */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Obsidian.Edm;

namespace Obsidian.Utils
{
    public class ModelUtil
    {

        public static string FieldsAliasJoin(IModel model, string separator)
        {
            StringBuilder sb = new StringBuilder();
            bool first = true;
            foreach (IModelField f in model.Fields)
            {
                if (first) first = false;
                else sb.Append(separator);
                sb.Append(f.Alias);
            }
            return sb.ToString();
        }

        public static string FieldsJoin<T>(IEnumerable<T> models, string alias, string separator) where T: OModel
        {
            StringBuilder sb = new StringBuilder();
            bool first = true;
            IModelField f;
            foreach (T m in models)
            {
                if (first) first = false;
                else sb.Append(separator);
                f = m.GetFieldByAlias(alias);
                if (f != null)
                {
                    if (f.IsNull)
                        sb.Append("");
                    else
                        sb.Append(f.ToString());
                }
            }
            return sb.ToString();
        }

        public static long[] ToLongArrray<T>(IEnumerable<T> models, string alias) where T : OModel
        {
            long[] arr = new long[models.Count<T>()];
            IModelField f;
            int i = 0;
            foreach (T m in models)
            {
                f = m.GetFieldByAlias(alias);
                if (f == null)
                    continue;
                if (f.IsNull)
                    continue;
                arr[i] = Convert.ToInt64(f.OValue);
                i++;
            }
            return arr;
        }

        public static string ToJsonString(IModel model)
        {
            JObject jo = new JObject();
            IModelField[] fields = model.Fields;
            foreach (IModelField field in fields)
            {
                if (String.IsNullOrEmpty(field.Alias))
                    continue;
                if (field.IsNull)
                    jo[field.Alias] = null;
                else
                {
                    if (field.Type == FieldType.Entity || field.Type == FieldType.EntityList)
                    {
                        continue;
                    }
                    else if (field.Type == FieldType.DateTime || field.Type == FieldType.Enum)
                    {
                        jo[field.Alias] = new JValue(field.ToString());
                    }
                    else
                    {
                        jo[field.Alias] = new JValue(field.OValue);
                    }
                }
            }
            return JsonConvert.SerializeObject(jo);
        }


        public static string ToJsonString<T>(IList<T> modelList) where T : IModel
        {
            JArray jarr = new JArray();
            foreach (IModel m in modelList)
            {
                JObject jo = new JObject();
                IModelField[] fields = m.Fields;
                foreach (IModelField field in fields)
                {
                    if (String.IsNullOrEmpty(field.Alias))
                        continue;
                    if (field.IsNull)
                        jo[field.Alias] = null;
                    else
                    {
                        if (field.Type == FieldType.DateTime)
                            jo[field.Alias] = new JArray(field.ToString());
                        else
                            jo[field.Alias] = new JValue(field.OValue);
                    }
                }
                jarr.Add(jo);
            }
            return JsonConvert.SerializeObject(jarr);
        }


        public static T ToModel<T>(string jsonString) where T : IModel, new()
        {
            JObject jo = (JObject)JsonConvert.DeserializeObject(jsonString);
            T o = new T();
            IModelField[] fields = o.Fields;
            foreach (IModelField field in fields)
            {
                JToken jt;
                if (jo.TryGetValue(field.Alias, out jt))
                {
                    try
                    {
                        JValue jv = (JValue)jt;
                        field.Set(jv.Value);
                    }
                    catch { continue; }
                }
            }
            return o;
        }

        public static T QueryStringToModel<T>(string queryString) where T : IModel, new()
        {
            T m = new T();
            string[] pair = queryString.Split('&');
            foreach (string str in pair)
            {
                string[] keyValue = str.Split('=');
                if (keyValue.Length >= 2)
                {
                    string name = keyValue[0];
                    string value = keyValue[1];
                    IModelField field = m.GetFieldByAlias(name);
                    if (field != null)
                    {
                        field.Set(value);
                    }
                }

            }
            return m;
        }

    }
}
